package com.cml.batisext.core.repository.mybatis.base;

import java.util.List;

import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;

import com.cml.batisext.core.bean.base.DatabaseBean;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoDeleteBatchSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoDeleteSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoInsertBatchSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoInsertSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoSelectCountSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoSelectSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoUpdateBatchSqlProvider;
import com.cml.batisext.core.repository.mybatis.base.sqlprovider.BaseDaoUpdateSqlProvider;
import com.google.common.collect.Lists;

/**
 * 实体通用dao,新建实体Dao时，只需继承此类，同时设置标注@GenerateDao，即可自动完成增删改查等基础操作
 * @author lwh
 *
 * @param <T> 实体类型
 */
public interface BaseDao<T extends DatabaseBean> {
	
	/** 通用 dao传入实体类型的参数名*/
	String ENTRY_PARAM_NAME = "bean";
    String LIST_PARAM_NAME = "list";
	/** 通用 dao传入主键的参数名*/
	String PK_PARAM_NAME = "id";
	/** 通用 dao传入需修改的列名参数的参数名*/
	String COLUMNS_PARAM_NAME = "columns";
	
    List<String> baseDaoMethods = Lists.newArrayList("selectByOrder","insert", "insertBatch", "deleteBatch", "deleteById", "delete", "update", "updateBatch", "updateColumns", "selectById", "select", "selectCount");

	@InsertProvider(type = BaseDaoInsertSqlProvider.class, method = "buildSql") 
	@Options(useGeneratedKeys = true)
	void insert(T bean);
	
    @InsertProvider(type = BaseDaoInsertBatchSqlProvider.class, method = "buildSql")
    @Options(useGeneratedKeys = true)
    Integer insertBatch(List<? extends T> beanList);

    @DeleteProvider(type = BaseDaoDeleteBatchSqlProvider.class, method = "buildSql")
    Integer deleteBatch(List<? extends T> beanList);

	@DeleteProvider(type = BaseDaoDeleteSqlProvider.class, method = "buildSql") 
    Integer deleteById(Long id);  
      
	@DeleteProvider(type = BaseDaoDeleteSqlProvider.class, method = "buildSql") 
	Integer delete(T bean);  
	
	@UpdateProvider(type = BaseDaoUpdateSqlProvider.class, method = "buildSql") 
	Integer update(T bean);

    @UpdateProvider(type = BaseDaoUpdateBatchSqlProvider.class, method = "buildSql")
    Integer updateBatch(List<? extends T> beanList);

	@UpdateProvider(type = BaseDaoUpdateSqlProvider.class, method = "buildSql") 
	Integer updateColumns(@Param(COLUMNS_PARAM_NAME)String[] columns , @Param("bean")T bean);

	@SelectProvider(type = BaseDaoSelectSqlProvider.class, method = "buildSql") 
	T selectById(Long id);
	
	@SelectProvider(type = BaseDaoSelectSqlProvider.class, method = "buildSql") 
	List<T> select(T bean);
	
	/**
	 * 
	 * @param bean 查询条件
	 * @param orderBy 排序字段即排序类型，按多个字段排序请一并传入，如： age desc,name asc
	 * @return
	 */
	@SelectProvider(type = BaseDaoSelectSqlProvider.class, method = "buildSql") 
	List<T> selectByOrder(@Param("bean")T bean,@Param("orderBy")String orderBy);
	
	@SelectProvider(type = BaseDaoSelectCountSqlProvider.class, method = "buildSql") 
	Long selectCount(T bean);
}
